package com.nagarro.assignment1.main;

import java.util.ArrayList;
import java.util.Scanner;

import com.nagarro.assignment1.factory.ItemFactory;
import com.nagarro.assignment1.helper.Constants;
import com.nagarro.assignment1.inventory.Item;
import com.nagarro.assignment1.validation.Validator;

/**
 * Class containing the main method. It takes in inputs from the user and
 * calls appropriate function for performing validation checks, after
 * parsing the input.
 * 
 * {@link Item}
 * @author Shreyasi Agrawal
 * @version 1.0
 */
public class MainClass {

	/**
	 * Main method
	 * @param args
	 */
	public static void main(String[] args) {
		ArrayList<Item> arr;
		arr = takeInput();
		display(arr);
	}

	/**
	 * Method to display the final output
	 * @param arr2 
	 */
	private static void display(ArrayList<Item> arr2) {
		double bill = 0;

		for(int i = 0; i < arr2.size(); i++) {
			bill += arr2.get(i).total;
		}

		System.out.println(Constants.BILL + bill);
	}

	/**
	 * Method to get object according to type of item
	 * and assign values to object's variables
	 * @param type 
	 * @param quantity 
	 * @param price 
	 * @param name 
	 */
	private static Item createObject(String name, String price, String quantity, String type) {
		Item itemObject = null;

		// Call Item Factory to create appropriate object
		ItemFactory factory = new ItemFactory();
		itemObject = factory.getItem(type);

		// set name, price and type of the item
		itemObject.name = name;
		itemObject.price = Double.parseDouble(price);
		itemObject.type = type;
		itemObject.tax = itemObject.calculate(itemObject.price);
		itemObject.total = (itemObject.tax + itemObject.price) * Integer.parseInt(quantity);

		// print output for item
		System.out.println(Constants.DISPLAY);
		System.out.println(name + "\t" + price + "\t" + itemObject.tax + "\t" + itemObject.total);

		return itemObject;

	}

	/**
	 * Method to take input from user
	 * @return 
	 */
	private static ArrayList<Item> takeInput() {
		String input;
		String repeat = Constants.REPEAT;
		Item itemObject = null;

		ArrayList<Item> arr = new ArrayList<Item>();

		Scanner scan = new Scanner(System.in);

		do {
			System.out.println(Constants.ENTER_DETAILS);
			input = scan.nextLine();
			
			// checks if parsing successful
			itemObject = parse(input);

			// add created object to the arraylist
			if(itemObject != null) {
				arr.add(itemObject);
			}
			
			System.out.println(Constants.MORE_ITEMS);
			repeat = scan.nextLine();
		} while(repeat.equalsIgnoreCase(Constants.REPEAT));

		scan.close();
		return arr;
	}

	/**
	 * Method to parse the user input
	 * @param input The string which is to be parsed
	 * @return Returns whether the string was passed successfully or not
	 */
	private static Item parse(String input) {
		boolean correct;

		String price = "";
		String quantity = "";
		String type = "";
		String name = "";
		Item itemObject = null;

		// split the string using hyphen as delimiter
		String[] str = input.split("\u002D");

		// checks if the string contains less than 4 components
		if(str.length != 5) {
			System.out.println(Constants.WRONG_NO_OF_INPUTS);
			return null;
		}

		// checks if the first detail is the name of the item
		if(!str[1].substring(0, str[1].indexOf(Constants.SPACE))
				.equalsIgnoreCase(Constants.NAME)) {
			System.out.println(Constants.FIRST_PARAMETER_NAME);
			return null;
		}

		name = str[1].substring(str[1].indexOf(" ")+1);

		try {
			for(int i = 2; i < str.length; i++) {
				String[] temp = str[i].split("\\s+");

				if(temp[0].equalsIgnoreCase(Constants.PRICE)) {
					price = temp[1];
				}
				else if(temp[0].equalsIgnoreCase(Constants.QUANTITY)) {
					quantity = temp[1];
				}
				else if(temp[0].equalsIgnoreCase(Constants.TYPE)) {
					if(temp[1].equals(Constants.EMPTY)) {
						System.out.println(Constants.TYPE_NULL);
						break;
					}
					type = temp[1];
				}
			}
		} catch(ArrayIndexOutOfBoundsException e) {
		}

		// if code enters if, it means one of the detail is missing
		if(price.equals(Constants.EMPTY) || quantity.equals(Constants.EMPTY) ||
				type.equals(Constants.EMPTY) || name.equals(Constants.EMPTY)) {
			System.out.println(Constants.SOMETHING_MISSING);
			return null;
		}

		Validator v = new Validator();
		correct = v.validate(name, price, quantity, type);

		// checks if validation successful
		if(!correct) {
			return null;
		}
		
		itemObject = createObject(name, price, quantity, type);
		
		return itemObject;
	}
}